Данная глава содержит описание интерфейса к серверу реализованный на языке Си. Все функции описаные ниже находятся в библитотеках:
Для компиляции программы в UNIX системе команда будет выглядеть следующим образом:
Для Windows - Вам необходимо включить в проект библиотеку
ldbf.lib. И в секции define указать WINDOWS (необходимо
для использования вызовов функций LDBF API в стиле Windows).
При выполнении программы, ldbf.dll должна находиться или в текущем
каталоге, или в каталоге, где расположены системные динамические библиотеки
WINDOWS.
Синтаксис:
void ldbfSetDateFormat(char *picture)
Устанавливает формат вывода/ввода полей типа Date. В 'picture' указывается
маска типа "DD/MM/YY". Функции, которые возвращают значения полей
в случае поля типа Date, возвратят дату в указанном формате.
Пример:
ldbfSetDate("DD-MM-YY");
printf("%s\n",ldbfValue("table","date"));
Синтаксис:
void ldbfdate_assign(char *date,long julian_day)
Дата из длинного целого 'julian_day' конвертируется
в строку 'date' в формате CCYYMMDD (век, год, месяц, день). Данный формат принят
в среде xBase, именно так хранится дата в поле типа Date в файле DBF. Эта функция
является противоположной ldbfdate().
См. также: ldbfdate()
Синтаксис:
int ldbfday(char *date)
Возвращает день из даты, которая расположена в переменной
'date' в формате CCYYMMDD. Если дата пустая, возвращается 0.
Синтаксис:
int ldbfdow(char *date)
Возвращает день недели.
Значения дня недели:
Синтаксис:
void ldbfdate_format(char *date,char *result,char *picture)
Дата из формата CCYYMMDD преобразуется в переменную
'result' используя маску 'picture'. В
маске может находится любое сочетание специальных символов: CC - век, YY - год, MM - месяц,
DD - день.
Если указано более чем два символа 'M', значение месяца будет
возвращено в виде слова (английское название месяца).
Пример:
char result[20]; memcpy( dt, 0, sizeof(dt) ); /* Oct 02, 1990 */ ldbfdate_format( "19901002", result, "YY.MM.DD" ); /* "result" будет содержать "90.10.02" */ ldbfdate_format( "19901002", result, "CCYY.MM.DD" ) ; /* "result" будет содержать "1990.10.02" */ ldbfdate_format( "19901002", result, "MM/DD/YY" ) ; /* "result" будет содержать "10/02/90" */ ldbfdate_format( "19901002", result, "MMM DD/CCYY" ); /* "result" будет содержать "Oct 02/1990" */
Синтаксис:
void ldbfdate_init(char *date,char *value,char *picture)
Переменная 'date' инициализируется датой в формате
CCYYMMDD, которое берется из переменной 'value'. Эта переменная содержит дату
в формате, представленном переменной 'picture'. При обработке дат в программе
и если они храняться в формате, отличном от CCYYMMDD, необходимо их конвертировать
данной функцией перед занесением в поле записи. По своему назначению ldbfdate_init() является
противоположностью функции ldbfdate_format(). Если какая-то часть даты
в переменной 'value' опущена, то это значение будет взято из даты 1 января
1980 года.
Пример:
char day[7]; ldbfdate_init( day, "Oct 07/90", "MMM DD/YY" ) ; /* Переменная "day" будет содержать "19901007" */ ldbfdate_init( day, "08/07/1989", "MM/DD/CCYY" ); /* Переменная "day" будет содержать "19890807". */ ldbfdate_init( day, "08/07/1989", "DD/MM/CCYY" ) ; /* Переменная "day" будет содержать "19890708". */
Синтаксис:
long ldbfdate(char *date)
Данная функция переводит строку даты из формата dBase в дату представленную
длиным целым числом.
Пример:
char date[8];
long julian_day;
memcpy( date, "19901031", sizeof(date)) ;
julian_day = ldbfdate( date ) + 1 ;
ldbfdate_assign( date, julian_day )
См. также:
ldbfdate(), ldbfassign_long()
Синтаксис:
int ldbfmonth(char *date)
Возвращается месяц из даты в виде числа от 1 до 12.
Синтаксис:
void ldbftime_now(char *time)
Данная функция помещает текущее время в переменную 'time'.
Время заполняется в формате 'HH:MM:SS',что означает:
Заметим, что '24:00:00' есть тоже самое, что и '00:00:00'.Разница
только в том, что '24:00:00' означает конец суток, а '00:00:00' - начало.
Пример:
char ti[9]; ldbftime_now( ti ) ; ti[8] = (char)0; /* добавляем \0 для "printf" */ printf( " Текущее время: %s\n",ti);
Синтаксис:
void ldbftoday(char *date)
В переменную 'date' заносится текущая дата в формате CCYYMMDD.
Пример:
char day[9];
/* "day" инициализация текущей системной датой */
ldbftoday(day)
Синтаксис:
int ldbfyear(char *date)
Полный год возвращается в виде числа.
Пример:
char day[9]; int yr; memcpy(day,"19900101",sizeof(day) ); /* yr будет содержать (int) "1990". */ yr = ldbfyear( day );
Данная переменная хранит код ошибки последней операции. 0 означает,
что ошибки нет.
Данная переменная хранит системный код ошибки последней операции. 0 означает,
что ошибки нет.
Синтаксис:
char ldbfUserName(char *newname)
По умолчанию, в UNIX системах клиент LDBF автоматически
использует имя пользователя для соединения к серверу. Для клиента в среде
WINDOWS Вам необходимо сначала установить имя пользователя, который будет
соединяться с сервером. С помощью этой функции Вы можете установить
имя пользователя, которое будет передано серверу при соединении.
Если 'newname' равно 0, функция возвратит текущее имя пользователя.
Для смены имени, данная функция должна быть вызвана до вызова ldbfConnect().
Пример:
if(!strcmp(ldbfUserName(0),"magic")) /*заменяем имя пользователя*/ ldbfUserName("guest");
Синтаксис:
char *ldbfPassword(char *newpasswd,int crypt_pwd)
Данная функция возвращает или устанавливает пароль для доступа
к LDBF серверу. По умолчанию пароль не используется в UNIX системах,
так как пользователь уже ввел свой пароль при входе . Для клиентов
под Windows вызов данной функции обязателен. При вызове ldbfPassword() Вы можете
указать в каком виде находится новый пароль: он может быть просто строкой,
а может быть уже зашифрован. Для активизации проверки паролей, сервер должен
быть запущен с привилегиями root на UNIX системе. Если 'crypt_pwd' не равна
0, пароль уже закриптован, иначе пароль представлен в виде строки. При значении
'crypt_pwd' равен 1, пароль сбрасывается в значение по умолчанию. Если 'newpasswd' равна
0, ldbfPassword() возвращает старое значение пароля.
Пример:
if(!strcmp(ldbfUserName(0),"magic")) /* пароль для magic обязателен */ ldbfPassword("guest",0);
Синтаксис:
int ldbfPort(int newport)
Данная функция устанавливает TCP порт, на котором сервер ожидает
соединения с клиентом. По умолчанию используется порт 7979. Функция возвращает
текущий номер порта.
Пример:
ldbfPort(4679); /* назначаем порт для соединения */
sock = ldbfConnect("ldbfhost");
Синтаксис:
void *ldbfEventHandler(void (*newevent)())
Данная функция предназначенадля назначения обработчика событий в
программе пользователя. Сервер и другие программы могут посылать различные сообщения
и для того, чтобы их обрабатывать, необходимо назначить обработчик событий. Данный
обработчик будет вызываться при поступлении сообщения клиенту. Вы также можете
сами проверять сообщения путем вызова функции ldbfCheckEvent().
Формат обработчика:
void user_func(char *event_name,char *data);
где:
Пример:
void event_handler(char *name,char *data)
{
if(!strcmp(data,"alarm"))
fprintf(stdout,"It is time to go home,sir!!!");
}
Синтаксис:
void ldbfCheckEvent(int sock)
Эта функция проверяет, поступили ли какие-либо сообщения,
и если поступили, то вызывает обработчик событий.
Синтаксис:
void ldbfShutdown(int sock)
Закрывает соединение с сервером. При прекращении программы,
сервер сам распознает обрыв соединения и завершит сеанс. Но для более корректного
прекращения работы рекомендуется вызывать эту функцию.
Синтаксис:
ldbfDB *ldbfTableByNo(int no)
Возвращает указатель на открытую таблицу, у которой внутренний
номер равен 'no'. В основном пременяется в функциях обработки
результатов, возвращаемых процедурами базы данных.
См. также: ldbfCall()
Синтаксис:
ldbfDB *ldbfTableByName(char *name)
Возвращает указатель на открытую таблицу у которой алиас
равен 'name'.
Синтаксис:
int ldbfConnect(char *host)
Данная функция создает соединение с сервером.В качестве параметра выступает имя хоста, на котором запущен сервер. В случае когда, 'host' равен 0, используется локальная машина. Если система поддерживает Unix Domain протокол, связь на локальной машине будет вестись по этому протоколу. ldbfConnekt() возвращает номер соединения, который впоследствии будет использоваться многими функциями. Если произошла какая-нибудь ошибка, возвратится -1 и в переменную ldbf_errno будет занесен код ошибки. Вы можете установить две переменные среды, которые будут использоваться, независимо от переданных ldbfConnect() параметров.
С помощью данной функции Вы можете соединиться более чем с
одним сервером LDBF. При доступе к серверам необходимо только указывать
соответсвующие номера соединений, возвращенные данной функцией.
Пример:
int sock;
if((sock = ldbfConnect("localhost")) != -1) {
...
...
}
Синтаксис:
void ldbfCreateAliasDef(int sock,char *alias,char *pathname)
Cоздает алиас для вновь созданной таблицы. Для того, чтобы
создать новую таблицу и, чтобы ее могли использовать другие пользователи,
необходимо описать эту таблицу в системе с помощью функции ldbfCreateAliasDef(). Для выполнения
этой функции нужно иметь права на создание таблиц (параметер create_allow в файле ldbf.conf),
т. к. описание нового алиаса добавляется в ldbf.conf.
Пример:
ldbfCreateAliasDef(sock,"my_base","/home/base/dbf/new_base");
ldbfCreate(sock,"new_base",.......);
Синтаксис:
int ldbfExchange(int sock,char *alias,char *path)
Данная функция реализует способность сервера на ходу подменять
файлы данных. Вы можете не прерывая работы сервера и клиентов заменить
файл данных любой таблицы на любой другой файл DBF. Идентичность структур необязательна,
все зависит от базы данных и прикладных программ. При выполнении данной команды,
сервер переоткрывает новый файл DBF с тем же алиасом. Если какие-либо клиенты уже
открыли эту таблицу, они продолжат работу ничего не заметив. Описание нового
файла данных автоматически записывается в ldbf.conf вместо старого.
Внимание:
Если кто-то выполнял в это время транзакцию с этим файлом,
результаты будут потеряны. В случае ошибки возвращает -1 и устанавливает код ошибки
в ldbf_errno.
Пример:
ldbfExchange(sock,"my_base","/home/base/dbf/new_base.dbf");
Синтаксис:
void ldbfCloseall(int sock)
Закрывает все открытые таблицы для этого соединения.
Синтаксис:
int ldbfBegin(int sock)
Данная функция начинает транзакцию. Все изменения проводимые
в дальнейшем, будут накапливаться в журнале транзакции. Если во время транзакции
были изменены существующие записи, эти записи будут заблокированы до конца транзакции.
Если внутри транзакции происходит обращение к записи уже измененной в этой транзакции,
использоваться будут новые значения. Остальные пользователи не увидят изменений
до тех пор, пока транзакция не завершится. LDBF поддерживает вложенные транзакции.
Подтверждение транзакции закрепит все вложенные транзакции, тогда как откат отбросит изменения
только последней. Возвращает -1 в случае ошибки и устанавливает код ошибки в ldbf_errno.
Пример:
ldbfBegin(sock); ldbfAppend(...); ldbfAppend(...); ldbfBegin(sock); /* вложенная транзакция */ ldbfGo(...); ldbfUpdate(...); if(.......) /* если условие верно, отбрасываем последнюю ранзакцию */ ldbfAbort(sock); /* подтверждаем все транзакции */ ldbfCommit(sock);
Синтаксис:
void ldbfAbort(int sock)
Отбрасывает все изменения сделанные последней транзакцией.
См. также:
ldbfBegin()
Синтаксис:
int ldbfCommit(int sock)
Завершает транзакцию и записывает все изменения в базу данных.
Все блокировки освобождаются. Возвращает -1 в случае ошибки и устанавливает
код ошибки в ldbf_errno.
См. также: ldbfBegin()
Синтаксис:
void ldbfSetOnOff(int sock,int flag,int onoff)
Устанавливает различные параметры среды. 'flag' содержит
параметр, а onoff может принимать 1 в случае установки параметра и 0, в случае
сброса параметра.
На данный момент реализованы следующие флаги:
SET_DELETED - устанавливает режим отображения удаленных записей. При
установленном флаге, удаленные записи не будут возвращаться функциями:
ldbfSkip, ldbfSeek,
ldbfTop, ldbfBottom().
Пример:
/* не просматривать удаленные записи */
ldbfSetOnOff(sock,SET_DELETED,1);
См. также:ldbfFetchResult()
Синтаксис:
int ldbfCall(int sock,char *proc,char *param,void (*func)())
Вызывает процедуру базы данных 'proc' с параметрами
'param'. 'func' содержит указатель на функцию обработки
результатов, которые возвратит процедура.
Формат функции:
void func(long count);
где:
Результат можно получить с помощью функции ldbfFetchResult(). В случае
ошибки возвращает -1 и устанавливает код ошибки в ldbf_errno.
Пример:
void call_func(long count) { ldbfDB *data; ldbfRESULT *res; if(count) { while((res = ldbfFetchResult())) { db = ldbfTableByName(res->alias); /* Находим таблицу */ printf("%s %ld %s\n",db ? db->alias : "not opened", res->recno,res->data); if(db) { strcpy(db->record,res->data); /* копируем туда содержимое записи */ db->recno = res->recno; /* устанавливаем номер записи */ } } } } if(ldbfCall(sock,"find_user","smith",call_func) != -1) { /* если нет ошибки, выводим найденную запись */ printf("%s%s\n",ldbfValue("users","name"), ldbfValue("users","post")); }
См. также: ldbfTableByNo(),
ldbfFetchResult()
Синтаксис:
void ldbfClearResult()
Очищает список результатов.
Синтаксис:
RESULT * ldbfFetchResult()
Данная функция предназначена для получения результата,
полученного с помощью функции ldbfCall(). Функция возвращает указатель
на структуру типа RESULT, которая имеет следующие поля:
typdef struct { link_list link; char alias[16]; /* имя талицы или пустая строка если результат просто данные */ int recno; /* номер записи */ int len; /* длина поля data */ char *data; /* запись таблицы или данные */ } ldbfRESULT;
При достижении конца списка ldbfFetchResult() возвращает 0.
Пример:
/* Пример функции обработчика результата, который распечатывает все записи результата*/
void res_hadler(long count)
{
ldbfRESULT *res;
if(!count) return;
while((res = ldbfFetchResult()))
printf("%s %d %d %s\n",res->alias,res->recno,res->len,
res->data);
}
См. также : ldbfCall()
Синтаксис:
void ldbfRegisterEvent(int sock,char *event_name)
С помощью данной функции клиент регистрирует себя как получателя
события 'event_name'. Как только данное событие наступит, будет вызвана
процедура установленная функцией ldbfEventHandler().
Пример:
ldbfRegisterEvent(sock,"alarm");
См. также:ldbfRaiseEvent(),
ldbfEventHandler()
Синтаксис:
void ldbfRaiseEvent(int sock,char *event_name,char *data)
Данная функция посылает событие 'event_name' всем, кому оно предназначено.
'data' содержит данные, передаваемые с этим событием.
Пример:
char time[10]; ldbfTimeNow(time); /* время в форме hh:mm:ss */ if(time[0] == '2' && time[1] == '2') /* уже 22:00 ? */ ldbfRaiseEvent(sock,"alarm","Let's go home, buddy!!!");